#include "configuration.h"
#include <qdebug.h>

//程序运行便创建配置文件实例，线程安全
Configuration::Configuration() {
	QString fileName = "./config.ini";
	if (!QFile::exists(fileName)) {
		throw MyError(MyErrorType::FILE_NOT_EXISTS);
	}
	//读取文件信息
	try {
		m_settings = new QSettings(fileName, QSettings::IniFormat);
		m_settings->setIniCodec(QTextCodec::codecForName("UTF-8"));
		/*读取仪器配置信息*/
		m_settings->beginGroup("equipment");
		//读取英文名称并在在英文名称前填充空格
		this->equipment.abbreviation = m_settings->value("abbreviation", "").toString();
		this->equipment.name = m_settings->value("name", "").toString();
		this->equipment.version = m_settings->value("version", "").toString();
		this->equipment.eVersion = m_settings->value("eVersion", "").toString();
		m_settings->endGroup();

		/*读取软件logo路径*/
		m_settings->beginGroup("logo");
		this->logoPath.initLogo = m_settings->value("initLogo", "").toString();
		this->logoPath.homeLogo = m_settings->value("homeLogo", "").toString();
		this->logoPath.headerLogo = m_settings->value("headerLogo", "").toString();
		m_settings->endGroup();


		/*读取小数精度*/
		//m_settings->beginGroup("accuracy");
		//this->accuracy.value = m_settings->value("value", 1).toInt();
		//this->accuracy.area = m_settings->value("area", 2).toInt();
		//m_settings->endGroup();


		/*读取日志配置信息*/
		m_settings->beginGroup("log");
		this->log.path = m_settings->value("path", "./logs").toString();
		this->log.saveDays = m_settings->value("saveDays", 30).toInt();
		this->log.level = m_settings->value("level", "DEBUG").toString();
		m_settings->endGroup();


		/*读取图片缓存配置信息*/
		m_settings->beginGroup("cache");
		this->cache.path = m_settings->value("path", "./cache").toString();
		this->cache.saveDays = m_settings->value("saveDays", 30).toInt();
		m_settings->endGroup();


		/*读取相机信息*/
		m_settings->beginGroup("camera");
		this->camera.exposure = m_settings->value("exposure", 3000).toInt();
		this->camera.gain = m_settings->value("gain", 0).toInt();
		this->camera.whiteBalanceRed = m_settings->value("whiteBalanceRed", 2.1680).toDouble();
		this->camera.whiteBalanceGreen = m_settings->value("whiteBalanceGreen", 1.0000).toDouble();
		this->camera.whiteBalanceBlue = m_settings->value("whiteBalanceBlue", 1.4961).toDouble();
		this->camera.frameWidth = m_settings->value("width", 2048).toInt();
		this->camera.frameHeight = m_settings->value("height", 1440).toInt();
		this->camera.offsetX = m_settings->value("offsetX", 0).toInt();
		this->camera.offsetY = m_settings->value("offsetY", 0).toInt();
		this->camera.fps = m_settings->value("fps", 100).toInt();
		this->camera.frameCount = m_settings->value("frameCount", 1310).toInt();
		m_settings->endGroup();

		//读取相机内参系数
		m_settings->beginGroup("CameraMatrix");
		this->caliParas.CameraMatrix.push_back(m_settings->value("cameraMaOne", 2567.6321).toDouble());
		this->caliParas.CameraMatrix.push_back(m_settings->value("cameraMaTwo", 0).toDouble());
		this->caliParas.CameraMatrix.push_back(m_settings->value("cameraMaThree", 953.1875).toDouble());
		this->caliParas.CameraMatrix.push_back(m_settings->value("cameraMaFour", 0).toDouble());
		this->caliParas.CameraMatrix.push_back(m_settings->value("cameraMaFive", 2530.6676).toDouble());
		this->caliParas.CameraMatrix.push_back(m_settings->value("cameraMaSix", 671.9725).toDouble());
		this->caliParas.CameraMatrix.push_back(m_settings->value("cameraMaSeven", 0).toDouble());
		this->caliParas.CameraMatrix.push_back(m_settings->value("cameraMaEight", 0).toDouble());
		this->caliParas.CameraMatrix.push_back(m_settings->value("cameraMaNine", 1).toDouble());
		m_settings->endGroup();

		//读取相机畸变系数
		m_settings->beginGroup("DistCoeffs");
		this->caliParas.disCoeffs.push_back(m_settings->value("dissCoeffsOne", -0.0242).toDouble());
		this->caliParas.disCoeffs.push_back(m_settings->value("dissCoeffsTwo", -0.5166).toDouble());
		this->caliParas.disCoeffs.push_back(m_settings->value("dissCoeffsThree", 0.0018).toDouble());
		this->caliParas.disCoeffs.push_back(m_settings->value("dissCoeffsFour", -0.0075).toDouble());
		this->caliParas.disCoeffs.push_back(m_settings->value("dissCoeffsFive", 2.2117).toDouble());
		m_settings->endGroup();

		//读取步长
		m_settings->beginGroup("Step");
		this->caliParas.Step.push_back(m_settings->value("stepOne", -2.6795).toDouble());
		this->caliParas.Step.push_back(m_settings->value("stepTwo", -0.3522).toDouble());
		this->caliParas.Step.push_back(m_settings->value("stepThree", -2.7164).toDouble());
		m_settings->endGroup();

		//读取平面参数
		m_settings->beginGroup("PlaneParam");
		this->caliParas.PlaneParam.push_back(m_settings->value("paramA", -0.0314).toDouble());
		this->caliParas.PlaneParam.push_back(m_settings->value("paramB", -1.1187).toDouble());
		this->caliParas.PlaneParam.push_back(m_settings->value("paramC", -1.0000).toDouble());
		this->caliParas.PlaneParam.push_back(m_settings->value("paramD", 246.2756).toDouble());
		m_settings->endGroup();

		//读取串口数
		m_settings->beginGroup("serial");
		this->serialPortConfig.scannSpeed = m_settings->value("scannSpeed", 2.1680).toFloat();
		this->serialPortConfig.backSpeed = m_settings->value("backSpeed", 64000).toInt();
		this->serialPortConfig.eQuicken = m_settings->value("eQuicken", 0.6).toFloat();
		this->serialPortConfig.eWork = m_settings->value("eWork", 0.6).toFloat();
		this->serialPortConfig.eAwait = m_settings->value("eAwait", 0.2).toFloat();
		this->serialPortConfig.accelerated = m_settings->value("accelerated", 96000).toInt();
		this->serialPortConfig.retarded = m_settings->value("retarded", 96000).toInt();
		this->serialPortConfig.motoMcs = m_settings->value("motoMcs", 5).toInt();
		this->serialPortConfig.serialNum = m_settings->value("serialNum", "").toString();
		this->serialPortConfig.servoSerialNum= m_settings->value("servoSerialNum", "").toString();
		this->serialPortConfig.rotateDirection=m_settings->value("rotateDirection",1).toInt();
		this->serialPortConfig.rotateCount=m_settings->value("rotateCount",1).toInt();
		m_settings->endGroup();


		/*读取数据库连接信息*/
		m_settings->beginGroup("database");
		this->database.host = m_settings->value("host", "127.0.0.1").toString();
		this->database.port = m_settings->value("port", 3306).toInt();
		this->database.username = m_settings->value("username", "root").toString();
		this->database.password = m_settings->value("password", "root").toString();
		this->database.database = m_settings->value("database", "FOTF100").toString();
		m_settings->endGroup();

		
		m_settings->beginGroup("about");
		this->about.phone = m_settings->value("phone", "").toString();
		this->about.address = m_settings->value("address", "").toString();
		this->about.qrcode = m_settings->value("qrcode", "").toString();
		m_settings->endGroup();

		/*读取图像处理相关信息*/
		m_settings->beginGroup("imageUtil");
		this->imageProcessConfig.pixelSize = m_settings->value("pixelSize", 0.00586).toFloat();
		this->imageProcessConfig.focalLength = m_settings->value("focalLength", 12.07).toFloat();
		this->imageProcessConfig.poleLength = m_settings->value("poleLength", 250.0).toFloat();
		m_settings->endGroup();

		//读取曲面拟合的多项式系数-a
		m_settings->beginGroup("X_Coefficients");
		this->imageProcessConfig.aCoefficients.push_back(m_settings->value("a30", 0.0).toDouble());
        this->imageProcessConfig.aCoefficients.push_back(m_settings->value("a03", 0.0).toDouble());
        this->imageProcessConfig.aCoefficients.push_back(m_settings->value("a21", 0.0).toDouble());
        this->imageProcessConfig.aCoefficients.push_back(m_settings->value("a12", 0.0).toDouble());
        this->imageProcessConfig.aCoefficients.push_back(m_settings->value("a20", 0.0).toDouble());
        this->imageProcessConfig.aCoefficients.push_back(m_settings->value("a02", 0.0).toDouble());
        this->imageProcessConfig.aCoefficients.push_back(m_settings->value("a11", 0.0).toDouble());
        this->imageProcessConfig.aCoefficients.push_back(m_settings->value("a10", 0.0).toDouble());
        this->imageProcessConfig.aCoefficients.push_back(m_settings->value("a01", 0.0).toDouble());
        this->imageProcessConfig.aCoefficients.push_back(m_settings->value("a00", 0.0).toDouble());
		m_settings->endGroup();

		//读取曲面拟合的多项式参数-b
		m_settings->beginGroup("Z_Coefficients");
        this->imageProcessConfig.bCoefficients.push_back(m_settings->value("b30", 0.0).toDouble());
        this->imageProcessConfig.bCoefficients.push_back(m_settings->value("b03", 0.0).toDouble());
        this->imageProcessConfig.bCoefficients.push_back(m_settings->value("b21", 0.0).toDouble());
        this->imageProcessConfig.bCoefficients.push_back(m_settings->value("b12", 0.0).toDouble());
        this->imageProcessConfig.bCoefficients.push_back(m_settings->value("b20", 0.0).toDouble());
        this->imageProcessConfig.bCoefficients.push_back(m_settings->value("b02", 0.0).toDouble());
        this->imageProcessConfig.bCoefficients.push_back(m_settings->value("b11", 0.0).toDouble());
        this->imageProcessConfig.bCoefficients.push_back(m_settings->value("b10", 0.0).toDouble());
        this->imageProcessConfig.bCoefficients.push_back(m_settings->value("b01", 0.0).toDouble());
        this->imageProcessConfig.bCoefficients.push_back(m_settings->value("b00", 0.0).toDouble());
		m_settings->endGroup();

		//Y移动间隔
		float lead = 80/2.5;
		this->imageProcessConfig.YD = this->serialPortConfig.scannSpeed * lead / (std::pow(2, this->serialPortConfig.motoMcs) * 200 * this->camera.fps);
		qDebug() << "YD:" << this->imageProcessConfig.YD;

	} catch (const std::exception& e) {
		qCritical() << e.what();
		throw MyError(MyErrorType::FILE_READ_ERROR);
	} catch (...) {
		throw MyError(MyErrorType::UNKNOW_ERROR);
	}
}

Configuration::~Configuration() {
	delete m_settings;
}

Configuration& Configuration::getInstance() {
	//返回实例
	static Configuration instance;
	return instance;
}

bool Configuration::saveConfig() {
	if (m_settings == nullptr) {
		return false;
	}
	try {
		/*写入相机标定值*/
		m_settings->beginGroup("camera");
		m_settings->setValue("whiteBalanceRed", this->camera.whiteBalanceRed);
		m_settings->setValue("whiteBalanceGreen", this->camera.whiteBalanceGreen);
		m_settings->setValue("whiteBalanceBlue", this->camera.whiteBalanceBlue);
		m_settings->setValue("fps", this->camera.fps);
		m_settings->setValue("frameCount", this->camera.frameCount);
		m_settings->setValue("frameWidth", this->camera.frameWidth);
		m_settings->setValue("exposure", this->camera.exposure);
		m_settings->setValue("gain", this->camera.gain);
		m_settings->endGroup();


		//更新串口数据
		m_settings->beginGroup("serial");
		m_settings->setValue("scannSpeed", this->serialPortConfig.scannSpeed);
		m_settings->setValue("backSpeed", this->serialPortConfig.backSpeed);
		m_settings->setValue("eQuicken", this->serialPortConfig.eQuicken);
		m_settings->setValue("eWork", this->serialPortConfig.eWork);
		m_settings->setValue("eAwait", this->serialPortConfig.eAwait);
		m_settings->setValue("accelerated", this->serialPortConfig.accelerated);
		m_settings->setValue("retarded", this->serialPortConfig.retarded);
		m_settings->setValue("motoMcs", this->serialPortConfig.motoMcs);
		m_settings->setValue("serialNum", this->serialPortConfig.serialNum);
		m_settings->setValue("rotateDirection", this->serialPortConfig.rotateDirection);
		m_settings->setValue("rotateCount", this->serialPortConfig.rotateCount);
		m_settings->endGroup();

		////保存参数配置
		//m_settings->sync();
	} catch (const std::exception& e) {
		qCritical() << e.what();
		throw MyError(MyErrorType::FILE_WRITE_ERROR);
	} catch (...) {
		throw MyError(MyErrorType::UNKNOW_ERROR);
	}
	return true;
}